#include "server.h"

Servidor::Servidor(ServerCfg* cfg, Socket* sock) {
	this->cfg = *cfg;
	this->sock = sock;
}

Servidor::~Servidor() {

}

void Servidor::run() {
	string storage_path = cfg.GetStoragePath();
	string users_folder_name = "users_files";
	//Ruta donde se van a almacenar las carpetas de usuarios
	string files_path = storage_path + "/" + users_folder_name;
	category.info("Users folder path: " + files_path);
	//Recursos compartidos por todos los clientes
	unsigned int stored_bytes = 0;
	Mutex all_clients_mutex;
	//Guarda los indices usados hasta el momento por usuarios
	map<string, Index*> used_indexes;
	//El vector de ClientThreads
	//....................

	unsigned int start_time = time(0);
	ofstream ofs;
	ofs.open("./points.txt", ios::out);
	ofs << 0 << " " << stored_bytes << endl;
	ofs.close();

	Socket* new_socket;
	ClientThread* cc = 0;
	unsigned int max_time = 900;
	unsigned int verify_time = 10;
	ClientsCleaner cleaner(&clients_threads, max_time, verify_time,
			&all_clients_mutex, start_time, &stored_bytes);
	int listen_result = -1;
	try {
		listen_result = sock->Listen(cfg.GetPort());
		category.notice("Starting inactive clients cleaner");
		category.info("Max inactive seconds before close connection: %d",
				max_time);
		category.info(
				"Time interval (seconds) to search for inactive clients: %d",
				verify_time);
		cleaner.start();
	} catch (const CantListenException& e) {
		category.error("Error: Can't listen for incoming connections.");

	}
	while (listen_result != -1) {
		//Si hago shutdown desde el main, lanza excepcion y corto el while
		try {
			new_socket = sock->Accept();
		} catch (const AcceptingException& e) {
			category.notice("Stopping clients cleaner.");
			cleaner.stop();
			cleaner.join();
			break;
		}
		category.notice(
				"New incoming connection from ip "
						+ new_socket->GetConnectedInfo());
		cc = new ClientThread(new_socket, &clients_threads, &all_clients_mutex,
				&used_indexes, &files_path, &stored_bytes);
		cc->start();
		//Agrego a la lista de threads de clientes conectados
		all_clients_mutex.lock();
		clients_threads.push_back(cc);
		all_clients_mutex.unlock();
	}
	for (unsigned int i = 0; i < clients_threads.size(); i++) {
		//Paro los threads;
		category.info("Deleting all active user threads.");
		clients_threads.at(i)->stop();
		clients_threads.at(i)->join();
		delete clients_threads.at(i);
	}
	for (map<string, Index*>::iterator it = used_indexes.begin();
			it != used_indexes.end(); ++it) {
		category.info("Deleting all used indexes.");
		delete it->second;
	}
}
